import os
import requests
import json
import re
from lxml import etree
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext


# 获取视频和音频的播放地址
def get_play_url(url):
    try:
        r = requests.get(url, headers=header)
        info = re.findall('window.__playinfo__=(.*?)</script>', r.text)[0]
        data = json.loads(info)["data"]["dash"]
        video_url = data["video"][0]["baseUrl"]
        audio_url = data["audio"][0]["baseUrl"]
        html = etree.HTML(r.text)
        filename = html.xpath('//h1/text()')[0]
        return video_url, audio_url, filename
    except Exception as e:
        text_log.insert(tk.END, f"获取播放地址失败：{e}\n")
        return None, None, None


# 下载并保存视频和音频
def download_files(video_url, audio_url, filename, video_path, audio_path):
    try:
        text_log.insert(tk.END, "开始下载视频和音频...\n")
        video_content = requests.get(video_url, headers=header).content
        audio_content = requests.get(audio_url, headers=header).content

        with open(f'{video_path}/{filename}.mp4', 'wb') as f:
            f.write(video_content)
            text_log.insert(tk.END, "视频部分下载完毕\n")

        with open(f'{audio_path}/{filename}.mp3', 'wb') as f:
            f.write(audio_content)
            text_log.insert(tk.END, "音频部分下载完毕\n")
    except Exception as e:
        text_log.insert(tk.END, f"下载失败：{e}\n")


# 合并视频和音频
def combin_video_audio(filename, video_path, audio_path):
    try:
        text_log.insert(tk.END, "开始合并音频和视频...\n")
        cmd = fr"E:\D-Device\ffmpeg-7.0.2-essentials_build\bin\ffmpeg -i {video_path}/{filename}.mp4 -i {audio_path}/{filename}.mp3 -c:v copy -c:a aac -strict experimental -map 0:v -map 1:a {video_path}/output-{filename}.mp4 -loglevel quiet"
        os.system(cmd)
        text_log.insert(tk.END, "音频视频合并完毕\n")
        os.remove(f'{video_path}/{filename}.mp4')
        os.remove(f'{audio_path}/{filename}.mp3')
        text_log.insert(tk.END, '已删除多余的文件\n')
    except Exception as e:
        text_log.insert(tk.END, f"合并失败：{e}\n")


# 主操作函数
def start_download():
    url = entry_url.get()
    if not url:
        messagebox.showerror("错误", "请输入视频URL")
        return

    video_path = entry_video_path.get()
    audio_path = entry_audio_path.get()
    if not video_path or not audio_path:
        messagebox.showerror("错误", "请选择保存路径")
        return

    video_url, audio_url, filename = get_play_url(url)
    if not video_url or not audio_url or not filename:
        return

    download_files(video_url, audio_url, filename, video_path, audio_path)
    combin_video_audio(filename, video_path, audio_path)
    messagebox.showinfo("完成", "视频下载和合并完成！")


# 选择保存路径
def select_path(entry):
    path = filedialog.askdirectory()
    entry.delete(0, tk.END)
    entry.insert(0, path)


# 主窗口 pyinstaller --onefile 
root = tk.Tk()
root.title("Bilibili视频下载器")

# 设置请求头
header = {
    "cookie":"buvid4=53855CF9-7247-C537-E51A-0B6D259A1A5D50099-022061714-sHZIxuDLcjDGBXKIIuBxbQ%3D%3D; buvid_fp_plain=undefined; LIVE_BUVID=AUTO3616554485062530; rpdid=|(JRuY~mu~)|0J'uYY)Yl|lk|; buvid3=6A22047A-19C0-9803-6E43-9142591826DB52081infoc; enable_web_push=DISABLE; header_theme_version=CLOSE; DedeUserID=69099344; DedeUserID__ckMd5=655bb4a0e498607b; is-2022-channel=1; b_nut=100; _uuid=A1B923FF-562C-8E1B-35E5-FB3D9DD2D107125820infoc; fingerprint=43849032b88511503faa10691d18c40e; buvid_fp=43849032b88511503faa10691d18c40e; enable_feed_channel=ENABLE; home_feed_column=5; browser_resolution=1661-893; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDc2NTA4NTIsImlhdCI6MTc0NzM5MTU5MiwicGx0IjotMX0.rM0ikftJGu-mmu9_DoO0fdawbSu-l3Qm528Qeet04kA; bili_ticket_expires=1747650792; SESSDATA=b5a4896c%2C1762997422%2C4cd36%2A51CjDgYX1HC7oOCNq3n5o0vJWP8X9-I4pYjNj0rJS3k1zlHTdafUC_MGNYvr6zfS43PywSVkJDOGNSMVVJS2p4TDRJMzM4aWlwY3BoOGI5WWZpc0lLc3d0WFJZVHN6V0RRRWpWLWc1ODR2VktXVDFBZGlyUWZTN2twUVJlMWhOUTZRWWxSa1dyTWFBIIEC; bili_jct=09270b25d6e05b414fbf77f03deee899; sec_ck=gF__pxi53f9T4OoibbvNitEHe7cLbBGhjnCbvuL2IO1yUiAtyiaz06NaJLNFRFN0W-BIVs7VvaukIqTEUN2I49tqSMBy75zxn_GfCqihE4FqL6CkKfJM8i6iw4HvnuzcZujGNzim_xPdmqMVaMNUoIIEIoxk_XfB3Bmw4kjRSYJMGS__9pIAajs91xgign0G0SzhM1B4GbAgabWnQWEZaJOf2v7OuoeNn6oDuPkpQZnfIEla4CIcUNa_543VBk1LxidvV3Z3dw!Mss; PVID=2; sid=7bbam4ic; CURRENT_QUALITY=0; bsource=search_baidu; b_lsid=10D8589B7_196E2ABC44D; bp_t_offset_69099344=1068258430663262208; CURRENT_FNVAL=4048",
    "referer": "https://www.bilibili.com",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
}

# 输入框：视频URL
tk.Label(root, text="视频URL:").grid(row=0, column=0, padx=10, pady=10)
entry_url = tk.Entry(root, width=50)
entry_url.grid(row=0, column=1, padx=10, pady=10)

# 输入框：视频保存路径
tk.Label(root, text="视频保存路径:").grid(row=1, column=0, padx=10, pady=10)
entry_video_path = tk.Entry(root, width=50)
entry_video_path.grid(row=1, column=1, padx=10, pady=10)
tk.Button(root, text="选择路径", command=lambda: select_path(entry_video_path)).grid(row=1, column=2, padx=10, pady=10)

# 输入框：音频保存路径
tk.Label(root, text="音频保存路径:").grid(row=2, column=0, padx=10, pady=10)
entry_audio_path = tk.Entry(root, width=50)
entry_audio_path.grid(row=2, column=1, padx=10, pady=10)
tk.Button(root, text="选择路径", command=lambda: select_path(entry_audio_path)).grid(row=2, column=2, padx=10, pady=10)

# 按钮：开始下载
tk.Button(root, text="开始下载", command=start_download).grid(row=3, column=0, columnspan=3, pady=10)

# 文本框：显示日志
text_log = scrolledtext.ScrolledText(root, width=70, height=10)
text_log.grid(row=4, column=0, columnspan=3, padx=10, pady=10)

root.mainloop()